home *** CD-ROM | disk | FTP | other *** search
- /*******************************************
-
- WDEF Patcher
- Steve Falkenburg MacDTS
- ©1991 Apple Computer
-
- This snippet shows how you can add a simple extra part to a WDEF without
- writing an entire WDEF. It also shows how to access the new part via
- FindWindow().
-
- 6/1/92 SJF fixed a5 problem in WDEF patch (StripAddress is glue, and a5 wasn't set up)
- 6/1/92 SJF fixed varCode bug that made zoom boxes not work (masked out high 8 bits)
-
- *******************************************/
-
- #include <Windows.h>
-
- /* add 2 to this when checking with FindWindow() ! */
-
- #define kOurHit 32
-
- Boolean gInBackground;
- Boolean gDone;
-
- void InitStuff(void);
- void EventLoop(WindowPtr window);
- void DoDrag(WindowPtr window,Point globMouse);
- void HandleMouseDowns(EventRecord *ev);
- void HandleContent(WindowPtr theWindow,EventRecord *ev);
- void HandleUpdates(WindowPtr wind);
- void DoDeActivate(WindowPtr window,Boolean chFlag);
- void DoActivate(WindowPtr window,Boolean chFlag);
- void HandleActivates(EventRecord *ev);
- void HandleSREvt(long message);
- void DoGrow(WindowPtr window,Point globMouse);
- void PatchWindowWDEF(WindowPtr window);
- pascal long MyWDEFPatch(short varCode,WindowPtr window,short message,long param);
- void HandleOurPart(WindowPtr window);
-
-
- /* this struct allows us to insert a WDEF patch safely. It contains a jump instruction
- and stores the old handle to the WDEF
- */
-
- typedef struct {
- short jmpInst;
- ProcPtr patchAddr;
- Handle oldAddr;
- long ourA5;
- } WDEFPatch, *WDEFPatchPtr, **WDEFPatchHndl;
-
-
- void main(void)
- {
- WindowPtr mainWindow;
- Rect bounds = {100,100,150,300};
-
- gInBackground = false;
- gDone = false;
-
- InitStuff();
- mainWindow = NewWindow(nil,&bounds,"\pWDEF Patcher",false,8,(WindowPtr)-1,true,0);
- PatchWindowWDEF(mainWindow);
- ShowWindow(mainWindow);
- EventLoop(mainWindow);
- }
-
-
- void InitStuff(void)
- {
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
- FlushEvents(everyEvent,0);
- }
-
-
- void EventLoop(WindowPtr window)
- {
- EventRecord ev;
-
- do {
- if (WaitNextEvent(everyEvent,&ev,10,nil)) {
- switch (ev.what) {
- case mouseDown:
- HandleMouseDowns(&ev);
- break;
- case updateEvt:
- HandleUpdates((WindowPtr)ev.message);
- break;
- case activateEvt:
- HandleActivates(&ev);
- break;
- case app4Evt:
- HandleSREvt(ev.message);
- break;
- }
- }
- } while (!gDone);
- }
-
-
- void HandleMouseDowns(EventRecord *ev)
- {
- WindowPtr theWindow;
- short part;
-
- part = FindWindow(ev->where,&theWindow);
-
- switch (FindWindow(ev->where,&theWindow)) {
- case inMenuBar:
- break;
- case inSysWindow:
- SystemClick(ev,theWindow);
- break;
- case inDrag:
- DoDrag(theWindow,ev->where);
- break;
- case inGoAway:
- if (TrackGoAway(theWindow,ev->where)) {
- gDone = true;
- }
- break;
- case inContent:
- HandleContent(theWindow,ev);
- break;
- case inGrow:
- DoGrow(theWindow,ev->where);
- break;
- case kOurHit+2: // remember, we're adding 2 so the FindWindow/WDEF
- HandleOurPart(theWindow); // codes match
- break;
- }
- }
-
-
-
- /* handles a mouse down in our added window part */
-
- void HandleOurPart(WindowPtr window)
- {
- long final;
-
- SetPort(window);
- InvertRect(&window->portRect);
- while (StillDown());
- InvertRect(&window->portRect);
- }
-
-
- /* DoDrag: Handles drag window events */
-
- void DoDrag(WindowPtr window,Point globMouse)
- {
- Rect dragRect;
-
- SetRect(&dragRect,-32000,-32000,32000,32000);
-
- DragWindow(window,globMouse,&dragRect);
- SetPort(window);
- }
-
-
- /* DoGrow: Handles grow window events */
-
- void DoGrow(WindowPtr window,Point globMouse)
- {
- long newSize;
- Rect windLimits;
- GrafPtr tempPort;
-
- SetRect(&windLimits,64,64,32000,32000);
-
- if ((newSize = GrowWindow(window,globMouse,&windLimits)) != 0) {
- GetPort(&tempPort);
- SetPort(window);
- SizeWindow(window,LoWord(newSize),HiWord(newSize),true);
- InvalRect(&window->portRect);
- SetPort(tempPort);
- }
- }
-
-
- void HandleContent(WindowPtr theWindow,EventRecord *ev)
- {
- GrafPtr savePort;
- Point where;
-
- where = ev->where;
- SetPort(theWindow);
-
- if (theWindow != FrontWindow()) {
- SelectWindow(theWindow);
- return;
- }
- }
-
-
- void HandleUpdates(WindowPtr wind)
- {
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(wind);
- BeginUpdate(wind);
- EraseRect(&wind->portRect);
- DrawGrowIcon(wind);
- EndUpdate(wind);
- SetPort(savePort);
- }
-
-
- void HandleActivates(EventRecord *ev)
- {
- if ((ev->modifiers & activeFlag) != 0) {
- DoActivate((WindowPtr)ev->message,((ev->modifiers & 0x0002) != 0));
- }
- else {
- DoDeActivate((WindowPtr)ev->message,((ev->modifiers & 0x0002) != 0));
- }
- }
-
-
- /* DoActivate: Performs activate tasks */
-
- void DoActivate(WindowPtr window,Boolean chFlag)
- {
- DrawGrowIcon(window);
- }
-
-
- /* DoDeActivate: Performs deactivate tasks */
-
- void DoDeActivate(WindowPtr window,Boolean chFlag)
- {
- DrawGrowIcon(window);
- }
-
-
- void HandleSREvt(long message)
- {
- if ((message >> 24) == 1)
- if ((message & 1) != 0) {
- gInBackground = false;
- SetCursor(&arrow);
- if (FrontWindow()) {
- HiliteWindow(FrontWindow(),true);
- DoActivate(FrontWindow(),true);
- }
- }
- else if (FrontWindow()) {
- gInBackground = true;
- HiliteWindow(FrontWindow(),false);
- DoDeActivate(FrontWindow(),true);
- }
- }
-
-
-
-
- /* this installs the WDEF patch into a window */
-
- void PatchWindowWDEF(WindowPtr window)
- {
- WDEFPatchHndl wdefHndl;
- WDEFPatchPtr wdefPatch;
- Handle oldAddr;
- unsigned long wdefEntry;
-
- wdefHndl = (WDEFPatchHndl)NewHandle(sizeof(WDEFPatch));
- if (MemError()!=noErr)
- ExitToShell();
-
- oldAddr = ((WindowPeek)window)->windowDefProc;
- if (GetMMUMode()) // 32-bit
- wdefEntry = (unsigned long)wdefHndl;
- else
- wdefEntry = (unsigned long)StripAddress(wdefHndl) | ((unsigned long)oldAddr&0xff000000);
-
- HLock(wdefHndl);
- wdefPatch = *wdefHndl;
- wdefPatch->oldAddr = oldAddr;
- wdefPatch->jmpInst = 0x4ef9; /*JMP*/
- wdefPatch->patchAddr = MyWDEFPatch;
- #ifdef __SYSEQU__
- wdefPatch->ourA5 = *(long *)CurrentA5;
- #else
- wdefPatch->ourA5 = (long)CurrentA5;
- #endif
- HUnlock(wdefHndl);
- ((WindowPeek)window)->windowDefProc = (Handle)wdefEntry;
- }
-
-
- pascal long MyWDEFPatch(short varCode,WindowPtr window,short message,long param)
- {
- WDEFPatchHndl wdPatch;
- pascal long (*wdefProc)(short varCode,WindowPtr window,short message,long param);
- Handle oldWDEF;
- long result;
- Rect ourRect,ourElementRect;
- Point *hitPt;
- Point mouse;
- long appA5,saveA5;
-
- wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
- appA5 = (**wdPatch).ourA5;
- saveA5 = SetA5(appA5);
-
- ourRect = (**((WindowPeek)window)->strucRgn).rgnBBox;
- SetRect(&ourElementRect,ourRect.right-32,ourRect.top+4,ourRect.right-20,ourRect.top+15);
-
- oldWDEF = (**wdPatch).oldAddr;
- HLock(oldWDEF);
- wdefProc = (void *)*oldWDEF;
- wdefProc = (void *)StripAddress(wdefProc);
- result = (wdefProc)(varCode,window,message,param);
-
- switch (message) {
- case wDraw:
- if (((WindowPeek)window)->visible) {
- PenNormal(); // draw our part
- InsetRect(&ourElementRect,-1,0);
- EraseRect(&ourElementRect);
- InsetRect(&ourElementRect,1,0);
- FrameRect(&ourElementRect);
- InsetRect(&ourElementRect,2,2);
- FrameRect(&ourElementRect);
- }
- break;
- case wHit:
- hitPt = (Point *)¶m; // hit test our part
- if (PtInRect(*hitPt,&ourElementRect))
- result = kOurHit;
- break;
- }
-
- HUnlock(oldWDEF);
-
- SetA5(saveA5);
-
- return result;
- }
-
-